package com.clinic.accessor.db;

import java.util.List;
import java.util.Set;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;

import com.clinic.entity.db.Patient;
import com.clinic.entity.db.User;
import com.clinic.entity.param.Index;
import com.clinic.entity.type.GenderType;

@Component
public class PatientAccessor extends AbstractDbAccessor<Patient> {
	
	public Patient getPatientById(long id) {
		DetachedCriteria criteria = DetachedCriteria.forClass(Patient.class);
		criteria.add(Restrictions.eq(User.Columns.USER_ID, id));
		return uniqueGeneric(criteria);
	}
	
	public List<Patient> getPatientsByGender(GenderType gender) {
		DetachedCriteria criteria = DetachedCriteria.forClass(Patient.class);
		criteria.add(Restrictions.eq(Patient.Columns.GENDER, gender));
		return listGeneric(criteria, new Index());
	}
	
	public Patient getPatientByName(String name) {
		DetachedCriteria criteria = DetachedCriteria.forClass(Patient.class);
		criteria.add(Restrictions.eq(User.Columns.NAME, name));
		return uniqueGeneric(criteria);
	}
	
	/*public List<Patient> getAllPatients(Index index) {
		DetachedCriteria criteria = DetachedCriteria.forClass(Patient.class);
		criteria.add(Restrictions.gt(User.Columns.USER_ID, 0L));
		return listGeneric(criteria, new Index());
	}*/
	
	public List<Patient> getPatientsNotInIds(Set<Long> userIds, Index index) {
		DetachedCriteria criteria = getCriteriaOfPatients();
		criteria.add(Restrictions.not(Restrictions.in(User.Columns.USER_ID, userIds)));
		return listGeneric(criteria, index);
	}
	
	public List<Patient> getPatients(Index index) {
		DetachedCriteria criteria = getCriteriaOfPatients();
		return listGeneric(criteria, index);
	}
	
	public int countPatients() {
		DetachedCriteria criteria = getCriteriaOfPatients();
		return getCount(criteria);
	}
	
	private DetachedCriteria getCriteriaOfPatients() {
		DetachedCriteria criteria = DetachedCriteria.forClass(Patient.class);
		return criteria;
	}
	
	public List<Patient> getOrderedPatientsByTerm(String term, String column, Index index) {
		DetachedCriteria criteria = getCriteriaOfPatientsByTerm(term, column);
		return listGeneric(criteria, index);
	}
	
	public int countPatientsByTerm(String term, String column) {
		DetachedCriteria criteria = getCriteriaOfPatientsByTerm(term, column);
		return getCount(criteria);
	}
	
	private DetachedCriteria getCriteriaOfPatientsByTerm(String term, String column) {
		DetachedCriteria criteria = DetachedCriteria.forClass(Patient.class);
		criteria.add(Restrictions.ilike(User.Columns.NAME, "%" + term + "%"));
		criteria.addOrder(Order.asc(column));
		return criteria;
	}
}
